﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ThridGroup.ERP.DTO;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.ObjectMapping;

namespace ThridGroup.ERP.RBAC
{
    /// <summary>
    /// 用户角色服务实现
    /// </summary>
    public class UserRoleServices : ApplicationService, IUserRoleServices
    {
        /// <summary>
        /// 用户角色仓储
        /// </summary>
        private readonly IRepository<UserRole, int> _userRoleRepository;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="userRoleRepository">用户角色仓储</param>
        public UserRoleServices(IRepository<UserRole, int> userRoleRepository)
        {
            _userRoleRepository = userRoleRepository;
        }

        /// <summary>
        /// 为用户分配角色
        /// </summary>
        /// <returns>添加成功的角色数量</returns>
        public async Task<int> AddUserRole(UserRoleDto userRoleDto)
        {
            if (userRoleDto == null)
                throw new ArgumentNullException(nameof(userRoleDto));

            if (userRoleDto.RoleId == null || !userRoleDto.RoleId.Any())
                throw new ArgumentException("必须选择至少一个角色");

            try
            {
                // 1. 删除用户现有角色
                await DeleteUserRoles(userRoleDto.UserId);

                // 2. 批量添加新角色
                var userRoles = userRoleDto.RoleId.Select(roleId => new UserRole
                {
                    UserId = userRoleDto.UserId,
                    RoleId = roleId
                }).ToList();

                await _userRoleRepository.InsertManyAsync(userRoles);
                return userRoles.Count;
            }
            catch (Exception ex)
            {
                throw new Exception($"分配角色失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取所有用户角色关系
        /// </summary>
        /// <returns></returns>
        public async Task<List<UserRoleDto>> QueryUserRole()
        {
            var userRoles = await _userRoleRepository.GetListAsync();
            
            // 按用户ID分组，合并角色ID
            var groupedUserRoles = userRoles
                .GroupBy(ur => ur.UserId)
                .Select(g => new UserRoleDto
                {
                    UserId = g.Key,
                    RoleId = g.Select(ur => ur.RoleId).ToList()
                })
                .ToList();

            return groupedUserRoles;
        }

        /// <summary>
        /// 获取指定用户的角色信息
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<UserRoleDto> GetUserRoles(int userId)
        {
            var userRoles = await _userRoleRepository.GetListAsync(ur => ur.UserId == userId);
            
            if (!userRoles.Any())
                return new UserRoleDto { UserId = userId, RoleId = new List<int>() };

            return new UserRoleDto
            {
                UserId = userId,
                RoleId = userRoles.Select(ur => ur.RoleId).ToList()
            };
        }

        /// <summary>
        /// 删除用户的所有角色
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<bool> DeleteUserRoles(int userId)
        {
            try
            {
                await _userRoleRepository.DeleteAsync(ur => ur.UserId == userId);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 获取用户完整角色信息
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <returns>用户角色信息</returns>
        public async Task<UserRoleDto> FullUserRole(int id)
        {
            var userRoles = await _userRoleRepository.GetListAsync(ur => ur.UserId == id);
            
            if (!userRoles.Any())
                return new UserRoleDto { UserId = id, RoleId = new List<int>() };

            return new UserRoleDto
            {
                Id = userRoles.FirstOrDefault()?.Id ?? 0,
                UserId = id,
                RoleId = userRoles.Select(ur => ur.RoleId).ToList()
            };
        }
    }
}
